package net.sf.amateras.air.as.syntax.sample;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import net.sf.amateras.air.as.syntax.DefaultSyntaxClass;
import net.sf.amateras.air.as.syntax.IContentAssistHelper;
import net.sf.amateras.air.as.syntax.ISyntaxClass;

public class SampleConstantAssistHelper implements IContentAssistHelper {

    private static List<DefaultSyntaxClass> topLevel;

    /**
     * 
     * @param document
     * @param documentOffset
     * @param previousWord
     */
    public List<ISyntaxClass> getSyntaxClasses(String document, int documentOffset,
            String previousWord) {

        //最初の読み込みだった場合にはリソースから情報を取り込み
        if (topLevel == null) {
            topLevel = new ArrayList<DefaultSyntaxClass>();
            String[] array = readStreamToStringArray();
            for (String s : array) {
                String typeName = s.substring(0, s.indexOf(" "));
                String method = s.substring(s.indexOf(" ") + 1);
                DefaultSyntaxClass syntax = new DefaultSyntaxClass();

                if (typeName.equals("function")) {
                    setFunctionProperty(method, syntax);

                } else if (typeName.equals("const")) {
                    setConstantProperty(method, syntax);
                }
                topLevel.add(syntax);
            }
        }

        //返すクラスを作成
        ArrayList<DefaultSyntaxClass> syntaxClasses = new ArrayList<DefaultSyntaxClass>();

        // (　がついていてもその前の文字で対象にするためはずす
        if (previousWord.endsWith("(")) {
            previousWord = previousWord.substring(0, previousWord.length() - 1);
        }

        for (int i = 0; i < topLevel.size(); i++) {
            DefaultSyntaxClass syntax = topLevel.get(i);
            //最初の文字が一致しているもののみ格納していく。
            if (syntax.getName().startsWith(previousWord)) {
                //変換する位置、文字などは再設定
                syntax.setReplacementLength(previousWord.length());
                syntax.setReplacementOffset(documentOffset - previousWord.length());
                syntaxClasses.add(syntax);
            }
        }
        return (List) syntaxClasses;
    }

    /**
     * functionの情報を解析してsyntaxに格納
     * @param information
     * @param syntax
     */
    private void setFunctionProperty(String information, DefaultSyntaxClass syntax) {
        char[] array = information.toCharArray();
        StringBuilder methodName = new StringBuilder();
        StringBuilder argInfo = null;
        StringBuilder returnInfo = null;
        for (char c : array) {
            if (c == '(') {
                if (argInfo == null) {
                    argInfo = new StringBuilder();
                    continue;
                }
            }
            if (c == ')') {
                if (returnInfo == null) {
                    returnInfo = new StringBuilder();
                    continue;
                }
            }

            if (returnInfo != null) {
                returnInfo.append(c);
            } else if (argInfo != null) {
                argInfo.append(c);
            } else {
                methodName.append(c);
            }
        }
        syntax.setReplacementString(methodName.toString() + "()");
        syntax.setCursorPosition(methodName.length() + 1);
        syntax.setType(ISyntaxClass.TYPE_FUNCTION);
        syntax.setName(methodName.toString());
        syntax.setInformationDisplayString(argInfo.toString());
        syntax.setDisplayString(information);

    }

    private void setConstantProperty(String information, DefaultSyntaxClass syntax) {
        String methodName = information.substring(0, information.indexOf(":"));
        syntax.setReplacementString(methodName.toString());
        syntax.setCursorPosition(methodName.length());
        syntax.setType(ISyntaxClass.TYPE_CONSTANT);
        syntax.setName(methodName);
        syntax.setDisplayString(information);
        syntax.setInformationDisplayString(information);
    }

    /**
     * read file, return StringArray.
     * @param filePath
     * @return
     */
    private String[] readStreamToStringArray() {
        BufferedReader bReader = null;
        InputStream input = null;

        try {
            input = getClass().getResourceAsStream("/syntax/TopLevel");
            bReader = new BufferedReader(new InputStreamReader(input));
            String line;
            ArrayList<String> list = new ArrayList<String>();

            while ((line = bReader.readLine()) != null) {
                if (line.length() == 0) {
                    continue;
                }
                list.add(line);
            }
            return list.toArray(new String[list.size()]);

        } catch (IOException e) {
            e.printStackTrace();
            return null;
        } finally {
            try {
                if (bReader != null) {
                    bReader.close();
                }
                if (input != null) {
                    input.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
